04 API 调用参数调优与功能扩展

API 调用参数调优与功能扩展

关联:索引

AI 工具使用:调参/批量/排错提示词模板(学生可直接复制)

使用方法:把你的代码/报错/实验记录粘贴到 {你的内容} 处;要求 AI 输出结构化结果(表格/步骤/清单),便于照做与复盘。

模板 1:生成分拣场景结构化输出 Prompt(稳定 JSON)

你是“仓储分拣系统”的提示词工程师。请为通义千问生成一个 Prompt,用于把用户的分拣指令解析成 JSON,要求:
1)输出必须是严格 JSON(不要 Markdown,不要解释文字);
2)字段固定为:intent、items、destination、priority、constraints、notes;
3)items 是数组,每个元素包含:name、quantity、unit(可为空字符串);
4)priority 只能取:high/normal/low;无法判断时给 normal;
5)destination 为空时填 "UNKNOWN";
6)给出 3 条“容易出错的指令样例”以及期望 JSON 结果。
 
我的业务背景/示例指令:{你的内容}

模板 2:参数对比实验设计(分拣指令理解)

请围绕“分拣指令理解的稳定性与结构化输出质量”,设计一个短时间内可完成的参数对比实验:
1)给 6 条分拣指令(包含多物品、多目的地、优先级、异常信息);
2)给 3 组参数组合(temperature、top_p、max_length),每组说明预期现象;
3)给记录表模板:参数→JSON可解析率→字段缺失率→是否跑题→一致性→结论;
4)给一条总建议:如何从‘能用’调到‘稳定可用’。
 
我的课堂要求:{你的内容}

模板 3:JSON 解析失败排查与修复(定位→修复→预防)

下面是我调用通义千问得到的输出(包含原始文本)以及解析报错。请按“定位→修复→预防”输出:
1)判断是哪类问题:模型输出不严格JSON / 字段缺失 / 夹带解释文字 / 编码与转义问题 / 代码解析逻辑问题;
2)给最短排查步骤(最多 6 步);
3)给可直接粘贴的 Prompt 改写方案(更稳定 JSON);
4)给代码改动要点(不超过 6 条)。
 
我的内容:{你的内容}

模板 4:生成批量调用代码(频控+重试+汇总)

你是 Python 实践课助教。请生成一份“批量调用通义千问 API”的示例代码,要求:
1)使用 dashscope SDK;Key 从环境变量 DASHSCOPE_API_KEY 读取;
2)输入是一组分拣指令列表(给出示例数据);
3)每次调用要求模型返回严格 JSON(用于分拣解析);
4)实现频率控制(固定间隔或令牌桶均可,但要简单);
5)遇到限流/网络失败能重试(指数退避),并把失败原因记录到结果中;
6)最终输出汇总:成功数、失败数、失败原因分布,以及前 3 条解析结果。
 
我的内容:{你的内容}

模板 5:高并发/限流问题解决方案

我在做分拣指令的批量调用,遇到限流/超时/并发失败。请在“不更换Key、不升级付费方案”的前提下给方案:
1)给出可执行的并发策略(串行/小并发/队列)与推荐参数;
2)给出重试与退避策略(如何判断需要退避);
3)给出结果缓存与去重建议(哪些请求可以复用结果);
4)给出可观测性建议:要记录哪些字段(request_id、耗时、失败码等)。
 
我的现状:{你的内容}

记住“调参是为了现象”,不是为了背定义。

参数 你能观察到的现象 分拣指令理解的建议
temperature 越大越发散、越可能加入“自由发挥” 通常偏低(0.0~0.4)提高稳定性
top_p 越大越开放、越容易出现多样表述 通常中等(0.6~0.9)搭配低温度
max_length / max_tokens 太小会截断 JSON,太大可能夹带解释 给足(256~800),并用 Prompt 强约束“只输出 JSON”
prompt 约束强度 约束越强越像“结构化工具” 明确字段、取值范围、输出格式,减少歧义

参数命名说明(SDK vs 控制台/HTTP)

2. Python 示例:调用 + 严格 JSON 输出 + 解析与格式化打印

import json
import os
import time
from http import HTTPStatus
 
import dashscope
from dashscope import Generation
 
dashscope.api_key = os.getenv("DASHSCOPE_API_KEY")
 
JSON_SCHEMA_TIP = (
    '只输出严格JSON,不要Markdown,不要解释文字。'
    '字段固定为:intent, items, destination, priority, constraints, notes。'
    'items是数组,每项包含:name, quantity, unit。'
    'priority只能是high/normal/low。destination为空则填"UNKNOWN"。'
)
 
def build_sorting_prompt(instruction: str) -> str:
    return (
        "你是仓储分拣系统的指令解析器。"
        f"{JSON_SCHEMA_TIP}"
        f"分拣指令:{instruction}"
    )
 
def call_qwen(prompt: str, temperature: float, top_p: float, max_length: int) -> str:
    if not dashscope.api_key:
        raise RuntimeError("未配置 DASHSCOPE_API_KEY")
    resp = Generation.call(
        model=Generation.Models.qwen_turbo,
        prompt=prompt,
        temperature=temperature,
        top_p=top_p,
        max_length=max_length,
    )
    if resp.status_code != HTTPStatus.OK:
        raise RuntimeError(
            f"调用失败: status_code={resp.status_code}, code={resp.code}, "
            f"message={resp.message}, request_id={resp.request_id}"
        )
    return resp.output.get("text", "").strip()
 
def parse_json_strict(text: str) -> dict:
    return json.loads(text)
 
def format_sorting_result(data: dict) -> str:
    items = data.get("items") or []
    items_text = ";".join(
        f'{it.get("name")} x{it.get("quantity")}{it.get("unit") or ""}' for it in items
    ) or "无"
    return (
        f'意图: {data.get("intent")}\n'
        f'目的地: {data.get("destination")}\n'
        f'优先级: {data.get("priority")}\n'
        f'物品: {items_text}\n'
        f'约束: {data.get("constraints")}\n'
        f'备注: {data.get("notes")}'
    )
 
if __name__ == "__main__":
    instruction = "把 3 个红色马克笔和 1 本笔记本送到 A 区 2 号货架,优先级高。"
    prompt = build_sorting_prompt(instruction)
    raw = call_qwen(prompt, temperature=0.2, top_p=0.8, max_length=512)
    data = parse_json_strict(raw)
    print(format_sorting_result(data))

成功标志

用同一条指令 A,分别运行 3 组参数(示例):

记录表(可复制到笔记):

参数组合 JSON可解析(是/否) 字段缺失(0/1/2…) 是否夹带解释文字 是否跑题 结论

目标:在“解析结果”基础上生成对用户友好的反馈,同时保留可追溯字段(目的地、物品、优先级)。

示例思路:

(可选)第二步调用示例:

def build_feedback_prompt(parsed: dict) -> str:
    return (
        "你是仓储分拣系统的反馈生成器。"
        "给用户一段不超过80字的中文反馈,要求包含:目的地、物品摘要、优先级、下一步动作。"
        f"分拣解析结果(JSON):{json.dumps(parsed, ensure_ascii=False)}"
    )
 
def generate_feedback(parsed: dict) -> str:
    prompt = build_feedback_prompt(parsed)
    return call_qwen(prompt, temperature=0.4, top_p=0.8, max_length=256)

1. 为什么要频控

2. 批量调用最小实现(串行 + 固定间隔 + 指数退避)

import collections
import re
import time
from http import HTTPStatus
from typing import Any

def _extract_status_code(error_text: str) -> int | None:
    m = re.search(r"status_code=(\d+)", error_text)
    return int(m.group(1)) if m else None

def _should_retry_by_status(status_code: int | None) -> bool:
    if status_code is None:
        return False
    return status_code in (
        int(HTTPStatus.TOO_MANY_REQUESTS),
        int(HTTPStatus.REQUEST_TIMEOUT),
        int(HTTPStatus.SERVICE_UNAVAILABLE),
        int(HTTPStatus.BAD_GATEWAY),
        int(HTTPStatus.GATEWAY_TIMEOUT),
    )

def call_with_retry(prompt: str, temperature: float, top_p: float, max_length: int, max_retries: int = 3) -> str:
    delay_s = 1.0
    last_error = ""
    for attempt in range(max_retries + 1):
        try:
            return call_qwen(prompt, temperature=temperature, top_p=top_p, max_length=max_length)
        except RuntimeError as e:
            last_error = str(e)
            status_code = _extract_status_code(last_error)
            if status_code is not None and not _should_retry_by_status(status_code):
                raise
            if attempt == max_retries:
                raise
            time.sleep(delay_s)
            delay_s = min(delay_s * 2, 8.0)
    raise RuntimeError(last_error or "重试失败")

def batch_parse_instructions(instructions: list[str], interval_s: float = 0.6) -> list[dict[str, Any]]:
    results: list[dict[str, Any]] = []
    for idx, ins in enumerate(instructions, start=1):
        prompt = build_sorting_prompt(ins)
        try:
            raw = call_with_retry(prompt, temperature=0.2, top_p=0.8, max_length=512)
            data = parse_json_strict(raw)
            results.append({"ok": True, "index": idx, "instruction": ins, "data": data})
        except Exception as e:
            results.append({"ok": False, "index": idx, "instruction": ins, "error": str(e)})
        time.sleep(interval_s)
    return results

def summarize_batch(results: list[dict[str, Any]]) -> str:
    ok = sum(1 for r in results if r.get("ok"))
    fail = len(results) - ok
    reasons = collections.Counter((r.get("error") or "UNKNOWN") for r in results if not r.get("ok"))
    top_reasons = "\n".join(f"- {k}: {v}" for k, v in reasons.most_common(3)) or "- 无"
    return f"成功: {ok}\n失败: {fail}\n常见失败原因(Top3):\n{top_reasons}"

if __name__ == "__main__":
    instructions = [
        "把 3 个红色马克笔和 1 本笔记本送到 A 区 2 号货架,优先级高。",
        "B 区缺货:把 12 瓶矿泉水、6 包纸巾补到 B-01,越快越好。",
        "把 2 箱牛奶送到冷藏区;如果冷藏区满了就先放暂存区。",
    ]
    results = batch_parse_instructions(instructions, interval_s=0.7)
    print(summarize_batch(results))
    for r in results[:3]:
        print(r["ok"], r.get("data") or r.get("error"))

作业(课后完成)

  1. 提交分拣场景下 API 参数调优测试报告:至少 3 组参数、测试结果、调优结论(含记录表)。
  2. 提交“响应格式解析 + 批量调用”的代码与运行截图(注意 Key 打码)。
  3. 提交 AI 辅助调优的交互记录(关键提示词与输出要点)及优化后的代码(体现落地改动)。
  4. 学号-姓名-分拣指令解析和批量调用.pdf,2026年3月19日22点前提交到博思平台。

附录

  1. 阿里云百炼大模型API参考文档。https://bailian.console.aliyun.com/cn-beijing/?spm=5176.29619931.J_SEsSjsNv72yRuRFS2VknO.2.167210d7tvhf9V&tab=api#/api/?type=model&url=3016809.